package com.xbongbong.sso.help;

import com.xbongbong.formula.service.FunctionService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.errorcodes.SsoErrorCodeEnum;
import com.xbongbong.sso.domain.entity.OauthCustomParamEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 授权步骤帮助类
 */
@Component
public class CalculationHelp {

    private static final Logger LOG = LoggerFactory.getLogger(CalculationHelp.class);

    @Resource
    private FunctionService functionService;

    /**
     * 获取值
     * "client_id"："client_id值"、"client_secret"："client_secret值"、a：SHA256(CONCATENATE(client_id, client_secret))
     *
     * a=>4hfgi93-g23049rugrtiojb4t0
     *
     * @param standardAttr 对应的销帮帮系统字段/自定义字段key
     * @param parameterMap 常量参数map
     * @param calculationCustomParameterMap 需要计算的自定义参数map
     *
     * @return
     */
    public String getValue(String standardAttr, Map<String, String> parameterMap,
                            Map<String, OauthCustomParamEntity> calculationCustomParameterMap) throws XbbException {
        Object value;
        //判断是否循环调用
        try {
            String calculationStr = getCalculationString(standardAttr, parameterMap, calculationCustomParameterMap, 0);
            value = functionService.expressRunValue(calculationStr);
        } catch (Exception e) {
            throw new XbbException(SsoErrorCodeEnum.API_ERROR_273002);
        }
        return Objects.isNull(value) ? "" : value.toString();
    }

    /**
     * 转换成可直接计算的字符串
     * "client_id"："client_id值"、"client_secret"："client_secret值"
     *
     * "client_id值" =》"client_id值"
     * client_id =》"client_id值"
     * SHA256(CONCATENATE(client_id, client_secret)) =》 SHA256(CONCATENATE("client_id值", "client_secret值"))
     *
     * @param standardAttr 对应的销帮帮系统字段/自定义字段key/公式
     * @param parameterMap 常量参数map
     * @param calculationCustomParameterMap 需要计算的自定义参数map
     * @param counter 计数器
     *
     * @return
     */
    private String getCalculationString(String standardAttr, Map<String, String> parameterMap,
                                        Map<String, OauthCustomParamEntity> calculationCustomParameterMap, Integer counter) throws XbbException {
        if (counter > 10) {
            throw new XbbException(SsoErrorCodeEnum.API_ERROR_273011);
        }
        //常量字段、自定义字段的所有key
        Set<String> keySet = new HashSet<>();
        keySet.addAll(parameterMap.keySet());
        keySet.addAll(calculationCustomParameterMap.keySet());

        //遍历所有的key，看是否有包含
        for (String key : keySet) {
            if (standardAttr.indexOf(key) == -1) {
                continue;
            }
            String value = parameterMap.get(key);
            //常量能对应上，替换公式上的值
            if (StringUtil.isNotEmpty(value)) {
                standardAttr = standardAttr.replace(key, value);
                continue;
            }
            OauthCustomParamEntity customParameter = calculationCustomParameterMap.get(key);
            if (Objects.nonNull(customParameter)) {
                standardAttr = standardAttr.replace(key, getCalculationString(customParameter.getValue(), parameterMap,
                        calculationCustomParameterMap, ++counter));
            }
        }
        return standardAttr;
    }
}
